package com.tupu.service.impl.admin;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tupu.common.PageResult;
import com.tupu.entity.admin.LabelInfo;
import com.tupu.entity.admin.LabelPropertyInfo;
import com.tupu.entity.admin.LabelVisualized;
import com.tupu.entity.admin.UidInfo;
import com.tupu.entity.dispatch.WarningEventFailurePlan;
import com.tupu.entity.neo4j.*;
import com.tupu.mapper.admin.LabelMapper;
import com.tupu.mapper.admin.PropertyMapper;
import com.tupu.mapper.admin.UidMapper;
import com.tupu.mapper.dispatch.WarningEventFailurePlanMapper;
import com.tupu.service.admin.NodeService;
import com.tupu.util.FileUtil;
import com.tupu.util.Neo4jUtil;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.io.*;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class NodeServiceImpl implements NodeService {

    @Autowired(required = false)
    private Neo4jUtil neo4jUtil;

    @Autowired(required = false)
    private UidMapper uidMapper;

    @Autowired(required = false)
    private LabelMapper labelMapper;

    @Autowired(required = false)
    private PropertyMapper propertyMapper;

    @Autowired(required = false)
    private WarningEventFailurePlanMapper warningEventFailurePlanMapper;

    /**
     * 新增实例节点
     *
     * @param node
     * @return
     */
    @Override
    public String createNode(NodeSingle node) {
        Map<String, Object> attrs = node.getAttrs();
        String uidName = (String) attrs.get("uid");
        // 截取neo4j 属性 ''
        String uid = uidName.substring(1, uidName.length() - 1);
        //图铺id
        Long nodeId = node.getNodeId();
        QueryWrapper<UidInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("node_id", nodeId);
        queryWrapper.eq("uid_name", uid);
        List<UidInfo> list = uidMapper.selectList(queryWrapper);
        if (list.size() != 0) {
            return "uid已存在";
        }
        UidInfo uidInfo = new UidInfo();
        uidInfo.setUidName(uid);
        uidInfo.setNodeId(nodeId);
        uidMapper.insert(uidInfo);
        neo4jUtil.createNode(node);
        return "新增成功";
    }

    /**
     * 新增实例（可视化）
     *
     * @param node
     * @return
     */
    @Override
    public String createNodeVis(NodeSingle node) {
        Map<String, Object> attrs = node.getAttrs();
        String uidName = (String) attrs.get("uid");
        // 截取neo4j 属性 ''
        String uid = uidName.substring(1, uidName.length() - 1);
        Long nodeId = node.getNodeId();
        QueryWrapper<UidInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("node_id", nodeId);
        queryWrapper.eq("uid_name", uid);
        List<UidInfo> list = uidMapper.selectList(queryWrapper);
        if (list.size() != 0) {
            return "uid已存在";
        }
        UidInfo uidInfo = new UidInfo();
        uidInfo.setUidName(uid);
        uidInfo.setNodeId(nodeId);
        uidMapper.insert(uidInfo);
        Long id = neo4jUtil.createNodeVis(node);
        return id.toString();
    }

    /**
     * 实例高级搜索
     *
     * @param node_id
     * @param label_id
     * @param property_id
     * @param property
     * @return
     */
    @Override
    public LabelVisualized nodeAdvancedSearch(Long node_id, Long label_id, Long property_id, String property) {
        LabelInfo labelInfo = labelMapper.selectById(label_id);
        LabelVisualized Vis = new LabelVisualized();
        List<Map<String, Object>> nodeList = new ArrayList<>();
        List<Map<String, Object>> linkList = new ArrayList<>();
        List<Map<String, Object>> tagsList = new ArrayList<>();
        Vis.setRootId(node_id);
        Vis.setLinks(linkList);

        List<NodeSimple> nodes = neo4jUtil.nodeAdvancedSearch(node_id, label_id, property_id, property);
        for (NodeSimple node : nodes) {
            Long id = node.getId();
            String name = node.getName();
            String label = neo4jUtil.findByCaseId(id);
            //颜色
            String color = labelMapper.findColorByNodeIdAndLabel(node_id, label);
            Map<String, Object> nodeMap = new HashMap<>();
            nodeMap.put("id", id.toString());
            nodeMap.put("color", color);
            nodeMap.put("borderWidth", "black");
            nodeMap.put("fontColor", "0");
            nodeMap.put("text", name);
            Map<String, Object> map = new HashMap<>();
            //标签
            map.put("tag", label);
            nodeMap.put("data", map);
            nodeList.add(nodeMap);
            Vis.setNodes(nodeList);
        }
        //设置tags，根据node_id查询标签颜色
        Map<String, Object> tagsMap = new HashMap<>();
        tagsMap.put("name", labelInfo.getLabel());
        tagsMap.put("color", labelInfo.getColor());
        tagsList.add(tagsMap);
        Vis.setTags(tagsList);
        return Vis;
    }

    /**
     * 实例关系搜索
     *
     * @param node_id
     * @param relation
     * @return
     */
    @Override
    public LabelVisualized relationSearch(Long node_id, String relation) {
        LabelVisualized Vis = new LabelVisualized();
        List<Map<String, Object>> nodeList = new ArrayList<>();
        List<Map<String, Object>> linkList = new ArrayList<>();
        List<Map<String, Object>> tagsList = new ArrayList<>();
        Vis.setRootId(node_id);
        Vis.setTags(tagsList);

        List<RelationListAll> list = neo4jUtil.relationSearch(node_id, relation);
        for (RelationListAll r : list) {
            Long startId = r.getStartId();
            String startLabel = neo4jUtil.findByCaseId(startId);
            String startColor = labelMapper.findColorByNodeIdAndLabel(node_id, startLabel);
            Map<String, Object> startNode = new HashMap<>();
            startNode.put("id", startId.toString());
            startNode.put("color", startColor);
            startNode.put("borderWidth", "black");
            startNode.put("fontColor", "0");
            startNode.put("text", neo4jUtil.findNameById(startId));
            Map<String, Object> map1 = new HashMap<>();
            map1.put("tag", "");
            startNode.put("data", map1);
            nodeList.add(startNode);

            Long endId = r.getEndId();
            String endLabel = neo4jUtil.findByCaseId(endId);
            String endColor = labelMapper.findColorByNodeIdAndLabel(node_id, endLabel);
            Map<String, Object> endNode = new HashMap<>();
            endNode.put("id", endId.toString());
            endNode.put("color", endColor);
            endNode.put("borderWidth", "black");
            endNode.put("fontColor", "0");
            endNode.put("text", neo4jUtil.findNameById(endId));
            Map<String, Object> map2 = new HashMap<>();
            map2.put("tag", "");
            endNode.put("data", map2);
            nodeList.add(endNode);
            //关系
            Map<String, Object> link = new HashMap<>();
            link.put("from", startId.toString());
            link.put("to", endId.toString());
            link.put("text", r.getType());

            linkList.add(link);
            List<Map<String, Object>> newList1 = nodeList.stream().distinct().collect(Collectors.toList());
            List<Map<String, Object>> newList2 = linkList.stream().distinct().collect(Collectors.toList());
            Vis.setNodes(newList1);
            Vis.setLinks(newList2);
        }
        return Vis;
    }

    /**
     * 所有实例属性值
     *
     * @param node_id
     * @param label_id
     * @param property_id
     * @return
     */
    @Override
    public List<String> findAllProperty(Long node_id, Long label_id, Long property_id) {
        LabelInfo label = labelMapper.selectById(label_id);
        LabelPropertyInfo property = propertyMapper.selectById(property_id);
        List<String> list = neo4jUtil.findAllProperty(label.getLabel(), node_id, property.getName());
        List<String> newList = list.stream().distinct().collect(Collectors.toList());
        return newList;
    }

    /**
     * 导入实例
     *
     * @param file_path
     * @param node_id
     * @throws IOException
     */
    @Override
    public void addNode(String file_path, Long node_id) throws IOException {

        File file = new File(file_path);
        InputStream inputStream;
        ClassPathResource resource = new ClassPathResource(file_path);
        inputStream = resource.getInputStream();
        FileUtils.copyInputStreamToFile(inputStream, file);
        String absolutePath = file.getAbsolutePath();

        List<List<String>> lists = null;
        try {
            lists = FileUtil.readCsvLine(absolutePath);
        } catch (FileNotFoundException | UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        //List<List<String>> lists = FileUtil.readCsvLine(file_path);

        //标签名
        List<String> lineList = lists.get(0);
        String label = lists.get(1).get(0);
        for (int i = 0; i < 3; i++) {
            lineList.remove(0);
        }
        neo4jUtil.importCsvNode(file_path, label, lineList, node_id);
    }

    /**
     * 导入实例关系
     *
     * @param file_path
     * @param node_id
     * @throws IOException
     */
    @Override
    public void addNodeRelation(String file_path, Long node_id) throws IOException {

        File file = new File(file_path);
        InputStream inputStream;
        ClassPathResource resource = new ClassPathResource(file_path);
        inputStream = resource.getInputStream();
        FileUtils.copyInputStreamToFile(inputStream, file);
        String absolutePath = file.getAbsolutePath();

        List<List<String>> lists = null;
        try {
            lists = FileUtil.readCsvLine(absolutePath);
        } catch (FileNotFoundException | UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        //本地导入
        //List<List<String>> lists = FileUtil.readCsvLine(file_path);

        //节点间关系
        String type = "";
        List<String> lineList = lists.get(0);
        for (String s : lineList) {
            if (s.equals("TYPE")) {
                //label的索引
                int index = lineList.indexOf(s);
                type = lists.get(1).get(index);
            }
        }
        neo4jUtil.importCsvRelation(file_path, type, node_id);
    }

    /**
     * 实例关系高级搜索
     *
     * @param node_id
     * @param start_label
     * @param start_proId
     * @param start_property
     * @param end_label
     * @param end_proId
     * @param end_property
     * @param relation
     * @return
     */
    @Override
    public LabelVisualized relationAdvancedSearch(Long node_id, Long start_label, Long start_proId, String start_property, Long end_label, Long end_proId, String end_property, String relation) {
        LabelVisualized Vis = new LabelVisualized();
        List<Map<String, Object>> nodeList = new ArrayList<>();
        List<Map<String, Object>> linkList = new ArrayList<>();
        List<Map<String, Object>> tagsList = new ArrayList<>();
        Vis.setRootId(node_id);
        Vis.setNodes(nodeList);
        Vis.setLinks(linkList);
        Vis.setTags(tagsList);

        String s1;
        String s2;
        String s3;

        if (start_property.length() != 0 && !start_property.isEmpty() && null != start_property) {
            LabelInfo startLabel = labelMapper.selectById(start_label);
            LabelPropertyInfo startPro = propertyMapper.selectById(start_proId);
            s1 = String.format("match (x:`%s`{node_id:'%s',`%s`:'%s'})-", startLabel.getLabel(), node_id, startPro.getName(), start_property);
        } else {
            s1 = String.format("match (x{node_id:'%s'})-", node_id);
        }

        if (relation.length() != 0 && !relation.isEmpty() && null != relation) {
            s2 = String.format("[r:`%s`{node_id:'%s'}]", relation, node_id);
        } else {
            s2 = String.format("[r{node_id:'%s'}]", node_id);
        }

        if (end_property.length() != 0 && !end_property.isEmpty() && null != end_property) {
            LabelInfo endLabel = labelMapper.selectById(end_label);
            LabelPropertyInfo endPro = propertyMapper.selectById(end_proId);
            s3 = String.format("-(y:`%s`{node_id:'%s',`%s`:'%s'}) return r", endLabel.getLabel(), node_id, endPro.getName(), end_property);
        } else {
            s3 = String.format("-(y{node_id:'%s'}) return r", node_id);
        }
        String cypherSql = s1 + s2 + s3;
        //System.out.println(cypherSql);
        List<RelationListAll> list = neo4jUtil.relationAdvancedSearch(cypherSql);
        for (RelationListAll r : list) {
            Long startId = r.getStartId();
            String startLabel = neo4jUtil.findByCaseId(startId);
            String startColor = labelMapper.findColorByNodeIdAndLabel(node_id, startLabel);
            Map<String, Object> startNode = new HashMap<>();
            startNode.put("id", startId.toString());
            startNode.put("color", startColor);
            startNode.put("borderWidth", "black");
            startNode.put("fontColor", "0");
            startNode.put("text", neo4jUtil.findNameById(startId));
            Map<String, Object> map1 = new HashMap<>();
            map1.put("tag", "");
            startNode.put("data", map1);
            nodeList.add(startNode);

            Long endId = r.getEndId();
            String endLabel = neo4jUtil.findByCaseId(endId);
            String endColor = labelMapper.findColorByNodeIdAndLabel(node_id, endLabel);
            Map<String, Object> endNode = new HashMap<>();
            endNode.put("id", endId.toString());
            endNode.put("color", endColor);
            endNode.put("borderWidth", "black");
            endNode.put("fontColor", "0");
            endNode.put("text", neo4jUtil.findNameById(endId));
            Map<String, Object> map2 = new HashMap<>();
            map2.put("tag", "");
            endNode.put("data", map2);
            nodeList.add(endNode);
            //关系
            Map<String, Object> link = new HashMap<>();
            link.put("from", startId.toString());
            link.put("to", endId.toString());
            link.put("text", r.getType());

            linkList.add(link);
            List<Map<String, Object>> newList1 = nodeList.stream().distinct().collect(Collectors.toList());
            Vis.setNodes(newList1);
            Vis.setLinks(linkList);
        }
        return Vis;
    }

    /**
     * 节点间最短路径
     *
     * @param node_id
     * @param start_label
     * @param start_proId
     * @param start_property
     * @param end_label
     * @param end_proId
     * @param end_property
     * @return
     */
    @Override
    public LabelVisualized shortestPath(Long node_id, Long start_label, Long start_proId, String start_property, Long end_label, Long end_proId, String end_property) {
        LabelVisualized Vis = new LabelVisualized();
        List<Map<String, Object>> nodeList = new ArrayList<>();
        List<Map<String, Object>> linkList = new ArrayList<>();
        List<Map<String, Object>> tagsList = new ArrayList<>();
        Vis.setRootId(node_id);
        Vis.setTags(tagsList);
        LabelInfo startLabel = labelMapper.selectById(start_label);
        LabelPropertyInfo startPro = propertyMapper.selectById(start_proId);
        LabelInfo endLabel = labelMapper.selectById(end_label);
        LabelPropertyInfo endPro = propertyMapper.selectById(end_proId);

        List<RelationListAll> list = neo4jUtil.shortestPath(node_id, startLabel.getLabel(), startPro.getName(), start_property, endLabel.getLabel(), endPro.getName(), end_property);
        if (!CollectionUtils.isEmpty(list)){
            for (RelationListAll rela : list) {
                Map<String, Object> startNode = new HashMap<>();
                Long startId = rela.getStartId();
                String label = neo4jUtil.findByCaseId(startId);
                String startName = neo4jUtil.findNameById(startId);
                String startColor = labelMapper.findColorByNodeIdAndLabel(node_id, label);
                startNode.put("id", startId.toString());
                startNode.put("color", startColor);
                startNode.put("borderWidth", "black");
                startNode.put("fontColor", "0");
                startNode.put("text", startName);
                Map<String, Object> map = new HashMap<>();
                map.put("tag", "");
                startNode.put("data", map);
                nodeList.add(startNode);

                Long endId = rela.getEndId();
                String label2 = neo4jUtil.findByCaseId(endId);
                String endName = neo4jUtil.findNameById(endId);
                String endLabelColor = labelMapper.findColorByNodeIdAndLabel(node_id, label2);
                Map<String, Object> endNode = new HashMap<>();
                endNode.put("id", endId.toString());
                endNode.put("color", endLabelColor);
                endNode.put("borderWidth", "black");
                endNode.put("fontColor", "0");
                endNode.put("text", endName);
                Map<String, Object> map2 = new HashMap<>();
                map2.put("tag", "");
                endNode.put("data", map2);
                nodeList.add(endNode);
                List<Map<String, Object>> newList = nodeList.stream().distinct().collect(Collectors.toList());
                Vis.setNodes(newList);

                //关系
                Map<String, Object> link = new HashMap<>();
                link.put("from", startId.toString());
                link.put("to", endId.toString());
                link.put("text", rela.getType());
                //link.put("color","#000000");
                linkList.add(link);
                linkList.remove(null);
                List<Map<String, Object>> mapList = linkList.stream().distinct().collect(Collectors.toList());
                Vis.setLinks(mapList);
            }
        } else {
            Vis.setNodes(nodeList);
            Vis.setLinks(linkList);
        }
        return Vis;
    }

    /**
     * 查询节点id和名称
     *
     * @param node_id
     * @return
     */
    @Override
    public List<NodeSimple> allNode(Long node_id) {
        List<NodeSimple> nodes = neo4jUtil.findAllNodeByNodeId(node_id);
        return nodes;
    }

    /**
     * 实例节点检索 （可视化）
     *
     * @param node_id
     * @param case_id
     * @param name
     * @return
     */
    @Override
    public LabelVisualized nodeSearch(Long node_id, Long case_id, String name) {

        String labelName = neo4jUtil.findByCaseId(case_id);
        QueryWrapper<LabelInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("node_id", node_id);
        queryWrapper.eq("label", labelName);
        LabelInfo label = labelMapper.selectOne(queryWrapper);

        LabelVisualized Vis = new LabelVisualized();
        List<Map<String, Object>> nodeList = new ArrayList<>();
        List<Map<String, Object>> linkList = new ArrayList<>();
        List<Map<String, Object>> tagsList = new ArrayList<>();
        Vis.setRootId(node_id);
        Vis.setLinks(linkList);
        Vis.setTags(tagsList);

        //颜色
        Map<String, Object> nodeMap = new HashMap<>();
        nodeMap.put("id", case_id.toString());
        nodeMap.put("color", label.getColor());
        nodeMap.put("borderWidth", "black");
        nodeMap.put("fontColor", "0");
        nodeMap.put("text", name);
        Map<String, Object> map = new HashMap<>();
        //标签
        map.put("tag", label.getLabel());
        nodeMap.put("data", map);
        nodeList.add(nodeMap);
        Vis.setNodes(nodeList);
        return Vis;
    }

    /**
     * 切换可视化显示属性
     *
     * @param node_id
     * @param label_id
     * @param property_id
     * @param property_name
     * @return
     */
    @Override
    public LabelVisualized changePropertyVis(Long node_id, Long label_id, Long property_id, String property_name) {
        LabelVisualized Vis = new LabelVisualized();
        List<Map<String, Object>> nodeList = new ArrayList<>();
        List<Map<String, Object>> linkList = new ArrayList<>();
        List<Map<String, Object>> tagsList = new ArrayList<>();
        Vis.setTags(tagsList);
        Vis.setRootId(node_id);
        Vis.setLinks(linkList);
        List<NodeSingle> nodes = neo4jUtil.findByNid(node_id);
        for (NodeSingle node : nodes) {
            Long id = node.getId();
            Map<String, Object> attrs = node.getAttrs();
            Map<String, Object> nodeMap = new HashMap<>();
            String label = neo4jUtil.findByCaseId(id);
            String color = labelMapper.findColorByNodeIdAndLabel(node_id, label);
            nodeMap.put("id", id.toString());
            nodeMap.put("color", color);
            nodeMap.put("borderWidth", "black");
            nodeMap.put("fontColor", "0");
            try {
                nodeMap.put("text", attrs.get(property_name).toString());
            } catch (Exception e) {
                nodeMap.put("text", attrs.get("name").toString());
            }
            Map<String, Object> map = new HashMap<>();
            //标签
            map.put("tag", label);
            nodeMap.put("data", map);
            nodeList.add(nodeMap);
            Vis.setNodes(nodeList);
        }
        //通过node_id 查找所有关系
        List<RelationListAll> relationListAlls = neo4jUtil.findRelationByNodeId(node_id);
        for (RelationListAll relation : relationListAlls) {
            Map<String, Object> linkMap = new HashMap<>();
            linkMap.put("from", relation.getStartId().toString());
            linkMap.put("to", relation.getEndId().toString());
            linkMap.put("text", relation.getType());
            linkList.add(linkMap);
            Vis.setLinks(linkList);
        }
        return Vis;
    }

    /**
     * 实例切换层级
     *
     * @param type
     * @param node_id
     * @param label_name
     * @param case_name
     * @param case_id
     * @return
     */
    @Override
    public LabelVisualized levelVis(Long type, Long node_id, String label_name, String case_name, String case_id) {
        LabelVisualized Vis = new LabelVisualized();
        List<Map<String, Object>> nodeList = new ArrayList<>();
        List<Map<String, Object>> linkList = new ArrayList<>();
        List<Map<String, Object>> tagsList = new ArrayList<>();
        Vis.setRootId(node_id);
        Vis.setTags(tagsList);
        List<RelationListAll> list = neo4jUtil.levelVis(node_id, type, case_id);
        for (RelationListAll rela : list) {
            Map<String, Object> startNode = new HashMap<>();
            Long startId = rela.getStartId();
            String startLabel = neo4jUtil.findByCaseId(startId);
            String startName = neo4jUtil.findNameById(startId);
            String startColor = labelMapper.findColorByNodeIdAndLabel(node_id, startLabel);
            startNode.put("id", startId.toString());
            startNode.put("color", startColor);
            startNode.put("borderWidth", "black");
            startNode.put("fontColor", "0");
            startNode.put("text", startName);
            Map<String, Object> map = new HashMap<>();
            map.put("tag", startLabel);
            startNode.put("data", map);
            nodeList.add(startNode);

            Long endId = rela.getEndId();
            String endLabel = neo4jUtil.findByCaseId(endId);
            String endName = neo4jUtil.findNameById(endId);
            String endLabelColor = labelMapper.findColorByNodeIdAndLabel(node_id, endLabel);
            Map<String, Object> endNode = new HashMap<>();
            endNode.put("id", endId.toString());
            endNode.put("color", endLabelColor);
            endNode.put("borderWidth", "black");
            endNode.put("fontColor", "0");
            endNode.put("text", endName);
            Map<String, Object> map2 = new HashMap<>();
            map2.put("tag", endLabel);
            endNode.put("data", map2);
            nodeList.add(endNode);
            List<Map<String, Object>> newList = nodeList.stream().distinct().collect(Collectors.toList());
            Vis.setNodes(newList);

            //关系
            Map<String, Object> link = new HashMap<>();
            link.put("from", startId.toString());
            link.put("to", endId.toString());
            link.put("text", rela.getType());
            linkList.add(link);
            linkList.remove(null);
            List<Map<String, Object>> mapList = linkList.stream().distinct().collect(Collectors.toList());
            Vis.setLinks(mapList);
        }
        return Vis;
    }

    /**
     * 实例列表 可视化
     *
     * @param nodeId
     * @param size
     * @return
     */
    @Override
    public LabelVisualized nodeListVis(Long nodeId, Long size) {
        LabelVisualized Vis = new LabelVisualized();
        List<Map<String, Object>> nodeList = new ArrayList<>();
        List<Map<String, Object>> linkList = new ArrayList<>();
        List<Map<String, Object>> tagsList = new ArrayList<>();
        Vis.setNodes(nodeList);
        Vis.setLinks(linkList);
        Vis.setRootId(nodeId);
        List<NodeSimple> nodes = neo4jUtil.findByNodeId(nodeId, size);
        for (NodeSimple node : nodes) {
            Long id = node.getId();
            String name = node.getName();
            String label = neo4jUtil.findByCaseId(id);
            //颜色
            String color = labelMapper.findColorByNodeIdAndLabel(nodeId, label.trim());
            Map<String, Object> nodeMap = new HashMap<>();
            nodeMap.put("id", id.toString());
            nodeMap.put("color", color);
            nodeMap.put("borderWidth", "black");
            nodeMap.put("fontColor", "0");
            nodeMap.put("text", name);
            Map<String, Object> map = new HashMap<>();
            //标签
            map.put("tag", label.trim());
            nodeMap.put("data", map);
            nodeList.add(nodeMap);
            Vis.setNodes(nodeList);
        }
        //通过node_id 查找所有关系
        List<RelationListAll> relationListAlls = neo4jUtil.findRelationByNodeId(nodeId);
        for (RelationListAll relation : relationListAlls) {
            Map<String, Object> linkMap = new HashMap<>();
            linkMap.put("from", relation.getStartId().toString());
            linkMap.put("to", relation.getEndId().toString());
            linkMap.put("text", relation.getType());
            linkList.add(linkMap);
            Vis.setLinks(linkList);
        }
        //设置tags，根据node_id查询标签颜色
        List<LabelInfo> labelLists = labelMapper.findGraphByNodeId(nodeId);
        for (LabelInfo label : labelLists) {
            Map<String, Object> tagsMap = new HashMap<>();
            tagsMap.put("name", label.getLabel());
            tagsMap.put("color", label.getColor());
            tagsList.add(tagsMap);
            Vis.setTags(tagsList);
        }
        return Vis;
    }

    /**
     * 通过实例id查询实例属性信息
     *
     * @param id
     * @return
     */
    @Override
    public NodeListOne findNodeById(Long id) {
        NodeListOne result = new NodeListOne();
        List<String> headList = new ArrayList<>();
        if (id != null) {
            List<Map<String, Object>> list = neo4jUtil.findById(id);
            result.setId(id);
            for (Map<String, Object> map : list) {
                for (String s : map.keySet()) {
                    headList.add(s);
                    if (s.equals("label")) {
                        String l = (String) map.get(s);
                        result.setLabel(l);
                    }
                    if (s.equals("name")) {
                        Object name = map.get(s);
                        result.setName(name.toString());
                    }
                }
            }
            result.setNode(list);
            result.setTableHead(headList);
        }
        return result;
    }

    /**
     * 根据关系名称 relationName、node_id 查询实例关系数据，分页
     *
     * @param page
     * @param size
     * @param relation_name
     * @param node_id
     * @return
     */
    @Override
    public PageResult<RelationListAll> findByRelationNameAndNodeId(Integer page, Integer size, String relation_name, Long node_id) {
        PageResult<RelationListAll> info = new PageResult<>();
        List<RelationListAll> relations = neo4jUtil.findRelationByName(relation_name, node_id);
        //去重
        List<RelationListAll> newLists = relations.stream().distinct().collect(Collectors.toList());
        List<RelationListAll> list = newLists.stream().skip((page - 1) * size).limit(size).collect(Collectors.toList());
        int total = newLists.size();
        info.setTotal((long) total);
        info.setList(list);
        info.setPage(Long.valueOf(page));
        info.setSize(Long.valueOf(size));
        info.setTotalPages((long) (total / size + (total % size != 0 ? 1 : 0)));
        return info;
    }

    /**
     * 根据图谱id和实例名称 label 查询节点，分页
     *
     * @param page
     * @param size
     * @param nodeId
     * @param label
     * @param case_name
     * @return
     */
    @Override
    public NodeListAll searchNodeByName(Integer page, Integer size, Long nodeId, String label, String case_name) {
        NodeListAll result = new NodeListAll();
        List<Map<String, Object>> list = new ArrayList<>();
        PageResult<Map<String, Object>> info = new PageResult<>();
        List<NodeSingle> nodes = neo4jUtil.findByLabelAndNodeId(label, nodeId, case_name);
        List<String> proList = new ArrayList<>();
        for (NodeSingle node : nodes) {
            Long id = node.getId();
            Map<String, Object> attrs = node.getAttrs();
            attrs.put("id", id);
            attrs.remove("node_id");
            list.add(attrs);
            result.setNode(list);
            for (String pro : attrs.keySet()) {
                proList.add(pro);
            }
        }
        result.setNode_id(nodeId);
        result.setLabel(label);
        //去重
        List<String> newProperty = proList.stream().distinct().collect(Collectors.toList());
        newProperty.remove("node_id");
        result.setTableHead(newProperty);
        List<Map<String, Object>> node = result.getNode();
        //分页
        List<Map<String, Object>> mapList = node.stream().skip((page - 1) * size).limit(size).collect(Collectors.toList());
        int total = node.size();
        info.setTotal((long) total);
        info.setList(mapList);
        info.setPage(Long.valueOf(page));
        info.setSize(Long.valueOf(size));
        info.setTotalPages((long) (total / size + (total % size != 0 ? 1 : 0)));
        result.setPage(info);
        result.setNode(null);
        return result;
    }

    /**
     * 根据关系id修改 节点间关系
     *
     * @param relation_id
     * @param startId
     * @param endId
     * @param typeId
     */
    @Override
    public void updateRelation(Long relation_id, Long startId, Long endId, Long typeId) {
        neo4jUtil.delRelationById(relation_id);
        neo4jUtil.CreateRelation(startId, endId, typeId);
    }

    /**
     * 上传故障预案 word文档
     *
     * @param file_path
     * @param node_id
     * @throws IOException
     */
    @Override
    public void uploadByWord(String file_path, Long node_id) throws IOException {
        File file = new File(file_path);
        InputStream inputStream;
        ClassPathResource resource = new ClassPathResource(file_path);
        inputStream = resource.getInputStream();
        FileUtils.copyInputStreamToFile(inputStream, file);
        String absolutePath = file.getAbsolutePath();
        FileInputStream in = new FileInputStream(absolutePath);//载入文档
        Map<String, Object> map = new HashMap<>();

        // 处理docx格式 office2007以后版本
        if (file_path.toLowerCase().endsWith("docx")) {
            //word 2007 图片不会被读取， 表格中的数据会被放在字符串的最后
            XWPFDocument xwpf = new XWPFDocument(in);//得到word文档的信息
            // 设置需要读取的表格  set是设置需要读取的第几个表格，total是文件中表格的总数
            //  int set = orderNum;
            // int num = set;
            // 过滤前面不需要的表格
/*            for (int i = 0; i < set - 1; i++) {
                it.hasNext();
                it.next();
            }*/

/*            int total = 0;
            while (itpre.hasNext()) {
                 itpre.next();
                 total += 1;
            }*/
            Iterator<XWPFTable> it = xwpf.getTablesIterator();//得到word中的表格
            while (it.hasNext()) {
                XWPFTable table = it.next();
                List<XWPFTableRow> rows = table.getRows();
                //读取每一行数据
                for (int i = 0; i < rows.size(); i++) {
                    XWPFTableRow row = rows.get(i);
                    //读取每一列数据
                    List<XWPFTableCell> cells = row.getTableCells();
                    String key1 = null;
                    String key2 = "";
                    String key3 = "";
                    String key4 = "";
                    String key5 = "";

                    String value1 = "";
                    String value2 = "";
                    String value3 = "";
                    String value5 = "";

                    for (int j = 0; j < cells.size(); j++) {
                        XWPFTableCell cell = cells.get(j);
                        if (cells.size() == 2) {
                            if (j == 0) {
                                key1 = cell.getText();
                            } else {
                                value1 = cell.getText().trim();
                            }
                        }

                        if (cells.size() == 4) {
                            if (j == 0) {
                                key2 = cell.getText();
                            } else if (j == 1) {
                                value2 = cell.getText().trim();
                            }
                            if (j == 2) {
                                key3 = cell.getText();
                            } else if (j == 3) {
                                value3 = cell.getText().trim();
                            }
                        }

                        if (cells.size() == 3) {
                            if (j == 1) {
                                key4 = cell.getText();
                                if (key4.equals("南网总调") || key4.equals("广东中调") || key4.equals("茂名调控")) {
                                    key5 = "主要控制目标" + "/" + key4;
                                }
                                if (key4.equals("上报单位") || key4.equals("上报对象") || key4.equals("上报内容")) {
                                    key5 = "事故信息上报" + "/" + key4;
                                }
                                if (key4.equals("发布单位") || key4.equals("发布对象") || key4.equals("发布内容")) {
                                    key5 = "事故信息发布" + "/" + key4;
                                }
                            } else if (j == 2) {
                                value5 = cell.getText();
                            }
                        }
                    }
                    map.put(key1, value1);
                    map.put(key2, value2);
                    map.put(key3, value3);
                    map.put(key5, value5);
                    map.remove(null);
                    map.remove("");
                    // 过滤多余的表格
/*                    while (num < total) {
                        it.hasNext();
                        it.next();
                        num += 1;
                    }*/
                }
                NodeSingle node = new NodeSingle();
                node.setNodeId(node_id);
                node.setAttrs(map);
                for (String s : map.keySet()) {
                    //名称
                    if (s.equals("事故预案名称")) {
                        node.setName(String.valueOf(map.get(s)));
                        //System.out.println(node.getName());
                    }
                    //标签
                    //  if (s.equals("编号")) {
                    //String label = String.valueOf(map.get(s)).substring(0, 2);
                    //StringBuffer buffer = new StringBuffer();
                    //buffer.append(label).append("预案");
                    //node.setLabelName(buffer.toString());
                    node.setLabelName("故障预案");
                    //System.out.println(node.getLabelName());
                    //  }
                }
                neo4jUtil.createNodeByWord(node);

                try {
                    String number = "";
                    WarningEventFailurePlan plan = new WarningEventFailurePlan();
                    //System.out.println(node.getAttrs()+"==========");
                    Map<String, Object> attrs = node.getAttrs();
                    plan.setName(attrs.get("name").toString());
                    if (attrs.containsKey("编号")) {
                        number = attrs.get("编号").toString();
                    }
                    if (attrs.containsKey("预案编号")) {
                        number = attrs.get("预案编号").toString();
                    }
                    plan.setNumber(number);
                    if (StringUtils.isNotEmpty(attrs.get("负责单位").toString())) {
                        plan.setPlace(attrs.get("负责单位").toString());
                    }
                    if (StringUtils.isNotEmpty(attrs.get("创建日期").toString())) {
                        plan.setCreateDate(attrs.get("创建日期").toString());
                    }
                    if (StringUtils.isNotEmpty(attrs.get("编制人").toString())) {
                        plan.setProducer(attrs.get("编制人").toString());
                    }
                    if (StringUtils.isNotEmpty(attrs.get("审核人").toString())) {
                        plan.setAuditor(attrs.get("审核人").toString());
                    }
                    if (StringUtils.isNotEmpty(attrs.get("概述").toString())) {
                        plan.setSummary(attrs.get("概述").toString());
                    }
                    if (StringUtils.isNotEmpty(attrs.get("事前运行方式").toString())) {
                        plan.setBeforeWay(attrs.get("事前运行方式").toString());
                    }
                    if (StringUtils.isNotEmpty(attrs.get("故障设置").toString())) {
                        plan.setFaultSetting(attrs.get("故障设置").toString());
                    }
                    if (StringUtils.isNotEmpty(attrs.get("事后运行方式").toString())) {
                        plan.setAfterWay(attrs.get("事后运行方式").toString());
                    }
                    if (StringUtils.isNotEmpty(attrs.get("事后风险分析").toString())) {
                        plan.setAfterRisk(attrs.get("事后风险分析").toString());
                    }
                    if (StringUtils.isNotEmpty(attrs.get("主要控制目标/南网总调").toString())) {
                        plan.setTotalNote(attrs.get("主要控制目标/南网总调").toString());
                    }
                    if (StringUtils.isNotEmpty(attrs.get("主要控制目标/广东中调").toString())) {
                        plan.setMiddleNote(attrs.get("主要控制目标/广东中调").toString());
                    }
                    if (StringUtils.isNotEmpty(attrs.get("主要控制目标/茂名调控").toString())) {
                        plan.setRegulation(attrs.get("主要控制目标/茂名调控").toString());
                    }
                    if (StringUtils.isNotEmpty(attrs.get("事故处理过程及要点").toString())) {
                        plan.setProcess(attrs.get("事故处理过程及要点").toString());
                    }
                    if (StringUtils.isNotEmpty(attrs.get("事故信息上报/上报单位").toString())) {
                        plan.setReportedPlace(attrs.get("事故信息上报/上报单位").toString());
                    }
                    if (StringUtils.isNotEmpty(attrs.get("事故信息上报/上报内容").toString())) {
                        plan.setReportedObject(attrs.get("事故信息上报/上报内容").toString());
                    }
                    if (StringUtils.isNotEmpty(attrs.get("事故信息上报/上报对象").toString())) {
                        plan.setReportedContent(attrs.get("事故信息上报/上报对象").toString());
                    }
                    if (StringUtils.isNotEmpty(attrs.get("事故信息发布/发布单位").toString())) {
                        plan.setPublishPlace(attrs.get("事故信息发布/发布单位").toString());
                    }
                    if (StringUtils.isNotEmpty(attrs.get("事故信息发布/发布内容").toString())) {
                        plan.setPublishObject(attrs.get("事故信息发布/发布内容").toString());
                    }
                    if (StringUtils.isNotEmpty(attrs.get("事故信息发布/发布对象").toString())) {
                        plan.setPublishContent(attrs.get("事故信息发布/发布对象").toString());
                    }
                    if (StringUtils.isNotEmpty(attrs.get("事故影响评估").toString())) {
                        plan.setAssess(attrs.get("事故影响评估").toString());
                    }
                    if (StringUtils.isNotEmpty(attrs.get("备注").toString())) {
                        plan.setRemarks(attrs.get("备注").toString());
                    }
                    //类别
                    String name = attrs.get("name").toString();
                    if (name.contains("母线")) {
                        plan.setCategory(2);
                    }
                    if (name.contains("全站")) {
                        plan.setCategory(1);
                    } else {
                        plan.setCategory(3);
                    }
                    //级别
                    //String number = attrs.get("编号").toString();
                    if (number.contains("较大")) {
                        plan.setLevel(6);
                    }
                    if (number.contains("一般")) {
                        plan.setLevel(7);
                    }
                    if (number.contains("一级")) {
                        plan.setLevel(1);
                    }
                    if (number.contains("二级")) {
                        plan.setLevel(2);
                    }
                    if (number.contains("三级")) {
                        plan.setLevel(3);
                    }
                    if (number.contains("四级")) {
                        plan.setLevel(4);
                    }
                    if (number.contains("五级")) {
                        plan.setLevel(5);
                    }
                    plan.setStateId(1);
                    warningEventFailurePlanMapper.insert(plan);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                //warningEventService.uploadWord(node,plan);
            }
        }
    }

    /**
     * 实例数据
     *
     * @param name
     * @param node_id
     * @param page
     * @param size
     * @return
     */
    @Override
    public PageResult<NodeSingle> nodeDataManagement(String name, Long node_id, Long page, Long size) {
        List<NodeSingle> nodesList = neo4jUtil.findNodeByName(name, node_id, page, size);
        for (NodeSingle node : nodesList) {
            node.setNodeId(node_id);
        }
        Long total = neo4jUtil.findAllNodeCount(name, node_id);
        PageResult<NodeSingle> info = new PageResult<>();
        info.setList(nodesList);
        info.setTotalPages(total / size + (total % size != 0 ? 1 : 0));
        info.setTotal(total);
        info.setPage(page);
        info.setSize(size);
        return info;
    }

    /**
     * 实例关系数据
     *
     * @param name
     * @param node_id
     * @param page
     * @param size
     * @return
     */
    @Override
    public PageResult<RelationListAll> nodeRelationDataManagement(String name, Long node_id, Long page, Long size) {
        List<RelationListAll> listAlls = neo4jUtil.findRelationByName(name, node_id, page, size);
        for (RelationListAll rela : listAlls) {
            String startName = neo4jUtil.findNameById(rela.getStartId());
            rela.setStartName(startName);
            String endName = neo4jUtil.findNameById(rela.getEndId());
            rela.setEndName(endName);
        }
        Long total = neo4jUtil.findAllRelationCount(name, node_id);
        PageResult<RelationListAll> info = new PageResult<>();
        info.setList(listAlls);
        info.setTotalPages(total / size + (total % size != 0 ? 1 : 0));
        info.setTotal(total);
        info.setPage(page);
        info.setSize(size);
        return info;
    }

    /**
     * 根据关系id 集合 删除节点间关系
     *
     * @param ids
     */
    @Override
    public void delRelationByIds(List<Long> ids) {
        for (Long id : ids) {
            neo4jUtil.delRelationById(id);
        }
    }

    /**
     * 根据实例id集合 删除节点
     *
     * @param ids
     */
    @Override
    public void delNodeByIds(List<Long> ids) {
        for (Long id : ids) {
            neo4jUtil.delNode(id);
        }
    }

    /**
     * 根据实例id删除节点,同时删除关系
     *
     * @param id
     */
    @Override
    public void delNodeById(Long id) {
        neo4jUtil.delNode(id);
    }

    /**
     * 根据关系id删除节点间关系
     *
     * @param relation_id
     */
    @Override
    public void delRelationById(Long relation_id) {
        neo4jUtil.delRelationById(relation_id);
    }

    /**
     * 根据图谱绑定node_id 查询实例的id及名称
     *
     * @param nodeId
     * @param size
     * @return
     */
    @Override
    public List<NodeSimple> findByNodeId(Long nodeId, Long size) {
        List<NodeSimple> nodes = neo4jUtil.findByNodeId(nodeId, size);
        return nodes;
    }

    @Override
    public void updateNode(NodeSingle node) {
        neo4jUtil.updateNode(node);
    }

    /**
     * 创建节点间关系
     *
     * @param startId
     * @param endId
     * @param typeId
     */
    @Override
    public void CreateRelation(Long startId, Long endId, Long typeId) {
        neo4jUtil.CreateRelation(startId, endId, typeId);
    }

    /**
     * 根据关系id，relation_id查询一条关系数据
     *
     * @param relation_id
     * @return
     */
    @Override
    public RelationListAll findOneRelation(Long relation_id) {
        RelationListAll oneRelation = neo4jUtil.findOneRelation(relation_id);
        return oneRelation;
    }

    /**
     * 实例数据
     *
     * @param node_id
     * @return
     */
    @Override
    public List<NodeSingle> nodeDataManagementAll(Long node_id) {
        List<NodeSingle> nodesList = neo4jUtil.findNodeByNodeId(node_id);
        for (NodeSingle node : nodesList) {
            node.setNodeId(node_id);
            Map<String, Object> attrs = node.getAttrs();
            attrs.remove("node_id");
        }
        return nodesList;
    }

    /**
     * 实例关系数据(不分页)
     *
     * @param node_id
     * @return
     */
    @Override
    public List<RelationListAll> nodeRelationDataManagementAll(Long node_id) {
        List<RelationListAll> listAlls = neo4jUtil.findAllRelationByNodeId(node_id);
        for (RelationListAll rela : listAlls) {
            String startName = neo4jUtil.findNameById(rela.getStartId());
            rela.setStartName(startName);
            String endName = neo4jUtil.findNameById(rela.getEndId());
            rela.setEndName(endName);
        }
        return listAlls;
    }

    /**
     * 新增实例 可视化
     *
     * @param node
     * @return
     */
    @Override
    public LabelVisualized addNodeVis(NodeSingle node) {
        LabelVisualized Vis = new LabelVisualized();

        Map<String, Object> attrs = node.getAttrs();
        String uidName = (String) attrs.get("uid");
        // 截取neo4j 属性 ''
        String uid = uidName.substring(1, uidName.length() - 1);
        Long nodeId = node.getNodeId();
        QueryWrapper<UidInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("node_id", nodeId);
        queryWrapper.eq("uid_name", uid);
        List<UidInfo> list = uidMapper.selectList(queryWrapper);
        if (list.size() != 0) {
            return Vis;
        }
        UidInfo uidInfo = new UidInfo();
        uidInfo.setUidName(uid);
        uidInfo.setNodeId(nodeId);
        uidMapper.insert(uidInfo);
        String id = neo4jUtil.createNodeVis(node).toString();
        LabelInfo labelList = labelMapper.selectById(node.getLabelId());
        String color = labelList.getColor();
        List<Map<String, Object>> nodeList = new ArrayList<>();
        Map<String, Object> nodeMap = new HashMap<>();
        nodeMap.put("id", id.toString());
        nodeMap.put("color", color);
        nodeMap.put("borderWidth", "black");
        nodeMap.put("fontColor", "0");
        nodeMap.put("text", node.getName());
        Map<String, Object> map = new HashMap<>();
        map.put("tag", labelList.getLabel());
        nodeMap.put("data", map);
        nodeList.add(nodeMap);
        Vis.setNodes(nodeList);
        Vis.setRootId(node.getNodeId());
        //link
        List<Map<String, Object>> linkList = new ArrayList<>();
        Vis.setLinks(linkList);
        //设置tags，标签颜色
        List<Map<String, Object>> tagsList = new ArrayList<>();
        Map<String, Object> tagsMap = new HashMap<>();
        tagsMap.put("name", labelList.getLabel());
        tagsMap.put("color", color);
        tagsList.add(tagsMap);
        Vis.setTags(tagsList);
        return Vis;
    }

}